package de.velvettear.squirrel.util;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import android.util.Log;

public class EncryptionHelper {

		
	protected final static String HEX = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	protected final static byte[] IV = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	
	public EncryptionHelper() {
		
	}
		
	public static String encrypt(String m_sText) {
		try {
			byte[] rawKey = getRawKey();
			byte[] result = encrypt(rawKey, m_sText.getBytes("UTF-8"));
			
			return toHex(result);	
		} catch (Exception e) {
			return "";
		}			
	}
	
	public static String decrypt(String m_sText) {
		try {			
			byte[] rawKey = getRawKey();
			byte[] encrypted = toByte(m_sText);
			byte[] result = decrypt(rawKey, encrypted);
			String decrypted = new String(result);
			 			 
			return decrypted;
		} catch (Exception e) {
			return "";
		}
	}

	protected static byte[] getRawKey() throws Exception {	
		byte[] encodedKey = null;
		byte[] tmp = IdentificationHelper.getSerialNumber().getBytes("UTF-8");
		if (tmp.length > 32) {
			encodedKey = new byte[32];
			for (int i = 0; i < 32; i++) {
				encodedKey[i] = tmp[i];
			}
		} else if (tmp.length < 32) {
			encodedKey = new byte[32];
			for (int i = 0; i < 32; i++) {
				encodedKey[i] = 0;
			}
			for (int i = 0; i < tmp.length; i++) {
				encodedKey[i] = tmp[i];
			}
			
		} else {
			encodedKey = tmp;
		}
		SecretKey sKey = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
		
		return sKey.getEncoded();
	}
	
	private static byte[] encrypt(byte[] rawKey, byte[] text) {
		try {
			SecretKeySpec sKeySpec = new SecretKeySpec(rawKey, "AES");
			
			IvParameterSpec ivSpec = new IvParameterSpec(IV);
			
			Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
			cipher.init(Cipher.ENCRYPT_MODE, sKeySpec, ivSpec);
			
			byte[] encrypted = cipher.doFinal(text);
			return encrypted;			
		} catch (Exception e) {
			return null;
		}
    }

    private static byte[] decrypt(byte[] raw, byte[] encrypted) {
    	try {
    		SecretKeySpec sKeySpec = new SecretKeySpec(raw, "AES");
    		
    		IvParameterSpec ivSpec = new IvParameterSpec(IV);
    		
    		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");    		
    		cipher.init(Cipher.DECRYPT_MODE, sKeySpec, ivSpec);
    		
    		byte[] decrypted = cipher.doFinal(encrypted);
    		return decrypted;    		
    	} catch (Exception e) {
    		return null;
    	}
    }

    public static String toHex(String text) {
    	try {
    		return toHex(text.getBytes("UTF-8"));
    	} catch (Exception e) {
    		if (e.getMessage() != null) {
    			Log.e("toHex()" , e.getMessage());
    		}
    		return "";
    	}
    }
    
    public static String fromHex(String hex) {
    	return new String(toByte(hex));
    }
    
    public static byte[] toByte(String hexString) {
        int length = hexString.length() / 2;
        
        byte[] result = new byte[length];
        for (int i = 0; i < length; i++) {
        	result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();        	
        }
        
        return result;
    }

    public static String toHex(byte[] buffer) {    	
    	
    	if (buffer == null) {
    		return "";        	
    	}
    	
    	StringBuffer result = new StringBuffer(2 * buffer.length);
    	for (int i = 0; i < buffer.length; i++) {
    		appendHex(result, buffer[i]);
        }
    	
        return result.toString();
    }
    
	private static void appendHex(StringBuffer buffer, byte b) {
        buffer.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
	}
		
}
